﻿using ASmile;
using ASmile.Helpers;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;

namespace ASmile.Extern.Lib.Rsp
{
    /// <summary>
    /// 串口异步响应
    /// </summary>
    public abstract class HttpResponseSerial : HttpResponseAsync
    {
        protected SerialPort SerialObj { get; set; }

        protected bool IsRuning { private set; get; } = false;

        protected byte[] Buffer { get; } = new byte[1024];
        /// <summary>
        /// 串口接收等待的毫秒数
        /// </summary>
        protected int ComReceivedWait { set; get; } = 50;

        void Start()
        {
            if (IsRuning) return;
            IsRuning = true;

            if (SerialObj != null)
            {
                if (SerialObj.IsOpen) SerialObj.Close();
            }
            SerialObj = new SerialPort();
            InitSerial(SerialObj);

            SerialObj.DataReceived -= ComDataReceived;
            SerialObj.DataReceived += ComDataReceived;

            if (!SerialObj.IsOpen) SerialObj.Open();
        }

        private void ComDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (!SerialObj.IsOpen) return;
            int offset = 0;
            try
            {
                while (SerialObj.IsOpen && SerialObj.BytesToRead > 0 && offset < Buffer.Length)
                {
                    if (offset + SerialObj.BytesToRead > Buffer.Length)
                    {
                        break; //缓存数据不足，或发送数据过快，分包处理
                    }
                    offset += SerialObj.Read(Buffer, offset, SerialObj.BytesToRead);

                    Thread.Sleep(ComReceivedWait);
                }
                if (offset == 0) return; //没读到

                DataReceived(Buffer, 0, offset);
            }
            catch (Exception ex)
            {
                string data = "";
                if (offset > 0)
                {
                    data = BytesHelper.ByteArrToHex(Buffer, 0, offset);
                }
                LogHelper.LogObj.Error($"接收串口数据发生异常, data:{data}", ex);
            }
        }

        protected abstract void InitSerial(SerialPort serialObj);

        protected abstract void DataReceived(byte[] data, int offset, int count);

        protected override void ReceiveJsonData(Dictionary<string, string> bodyData)
        {
            //接收到请求
            Start();
        }
    }
}
